
import html

def tuple_list_to_html_table(data: list[tuple], headers: list[str]) -> str:
    """
    将 list[tuple] 转换为HTML表格

    :param data: MySQL查询结果，每个元组代表一行数据
    :param headers: 表头列表，与数据列数需一致
    :return: HTML表格字符串
    """
    # 检查表头与数据列数是否匹配
    if data and len(headers) != len(data[0]):
        raise ValueError("表头列数与数据列数不匹配")

    # 开始构建表格
    table = []
    # 表格开始标签（添加边框和样式，可选）
    table.append('<table border="1" cellpadding="8" style="border-collapse: collapse; margin: 20px 0;">')

    # 表头部分
    if headers:
        table.append('  <thead>')
        table.append('    <tr style="background-color: #f0f0f0;">')
        for header in headers:
            # 转义表头中的特殊字符（如&、<、>）
            escaped_header = html.escape(str(header))
            table.append(f'      <th>{escaped_header}</th>')
        table.append('    </tr>')
        table.append('  </thead>')

    # 表体部分
    table.append('  <tbody>')
    if not data:  # 处理空数据
        table.append('    <tr><td colspan="{}" style="text-align: center;">无数据</td></tr>'.format(len(headers) if headers else 1))
    else:
        for row in data:
            table.append('    <tr>')
            for item in row:
                # 转义每个单元格的特殊字符
                escaped_item = html.escape(str(row[item]))
                table.append(f'      <td>{escaped_item}</td>')
            table.append('    </tr>')
    table.append('  </tbody>')

    # 表格结束标签
    table.append('</table>')

    # 拼接所有部分为完整HTML
    return '\n'.join(table)